#ifndef __IMAGE_H__
#define __IMAGE_H__

#include <iostream>
#include <cstdint>
#include <fstream>
#include <vector>

// 原来的对齐方式入栈 设置新的对齐方式为1字节对齐
#pragma pack(push,1)

// TGA头部信息
struct TGA_Header {
    std::uint8_t  idlength{};
    std::uint8_t  colormaptype{};
    std::uint8_t  datatypecode{};
    std::uint16_t colormaporigin{};
    std::uint16_t colormaplength{};
    std::uint8_t  colormapdepth{};
    std::uint16_t x_origin{};
    std::uint16_t y_origin{};
    std::uint16_t width{};
    std::uint16_t height{};
    std::uint8_t  bitsperpixel{};
    std::uint8_t  imagedescriptor{};
};
// 还原对齐方式
#pragma pack(pop)

// 颜色
struct TGAColor {

    // 每一个颜色的数据 B G R A
    std::uint8_t bgra[4] = {0,0,0,0};
    // 通道数
    std::uint8_t bytespp = {0};

    TGAColor() = default;
    // R G B A 四通道 的构造方法 bytespp = 4
    TGAColor(const std::uint8_t R, const std::uint8_t G, const std::uint8_t B, const std::uint8_t A=255) : bgra{B,G,R,A}, bytespp(4) { }
    // 只有 B 通道的构造  bytespp = 1
    TGAColor(const std::uint8_t v) : bgra{v,0,0,0}, bytespp(1) { }
    // 使用指针和通道数量进行初始化的构造 指针中数据的顺序为 B G R A
    TGAColor(const std::uint8_t *p, const std::uint8_t bpp) : bgra{0,0,0,0}, bytespp(bpp) {
        for (int i=0; i<bpp; i++)
            bgra[i] = p[i];
    }
    // []索引通道值 B G R A
    std::uint8_t& operator[](const int i)  { return bgra[i]; }

    // 颜色倍乘
    TGAColor operator*(const double& intensity) {
        TGAColor res = *this;
        // 逐通道 * 增益系数
        for (int i=0; i<4; i++){
             res.bgra[i]*=intensity;
             res.bgra[i] = std::max(0,    std::min(255,(int)res.bgra[i]));
        }
        return res;
    }
    
    void operator*= (const double& intensity){  
        *this = *this * intensity;
    }

    TGAColor operator +(const TGAColor& r) {
        TGAColor res = *this;
        for(int i = 0; i < 4; i++){
            res.bgra[i] += r.bgra[i];
        }
        return res;
    }

    void operator += (const TGAColor& r) {
        *this = *this + r;
    }

    TGAColor operator /(const float intensity) {
        TGAColor res = *this;
        for(int i = 0; i < 4; i++){
            res.bgra[i] /= intensity;
        }
        return res;
    }

    void operator /=(const float intensity) {
        *this = *this / intensity;
    }
};

// 图像
class TGAImage {
protected:
    // 数据
    std::vector<std::uint8_t> data;
    // 宽
    int width;
    // 高
    int height;
    // 图片类型
    int bytespp;
    // 加载数据
    bool   load_rle_data(std::ifstream &in);
    // 卸载数据
    bool unload_rle_data(std::ofstream &out) const;
public:
    // 图像类型枚举  灰度图      RGB     RGBA
    enum Format { GRAYSCALE=1, RGB=3, RGBA=4 };

    TGAImage();
    // 宽 高 通道数 构造
    TGAImage(const int w, const int h, const int bpp);
    // 读取 tga 文件
    bool  read_tga_file(const std::string filename);
    // 写 tag 文件
    bool write_tga_file(const std::string filename, const bool vflip=true, const bool rle=true) const;
    // 水平翻转 
    void flip_horizontally();
    // 垂直翻转
    void flip_vertically();
    // 图像大小
    void scale(const int w, const int h);
    // 读取数据 [x,y]
    TGAColor get(const int x, const int y) const;
    // 设置 [x,y] 的颜色
    void set(const int x, const int y, const TGAColor &c);
    // 宽度
    int get_width() const;
    // 高度
    int get_height() const;
    // 通道数
    int get_bytespp();
    // 缓存
    std::uint8_t *buffer();
    // 清空
    void clear();
};

#endif //__IMAGE_H__

